package com.innovation.ic.cyz.base.service.cyz.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.innovation.ic.cyz.base.mapper.cyz.BrandMapper;
import com.innovation.ic.cyz.base.mapper.cyz.ProductMapper;
import com.innovation.ic.cyz.base.mapper.cyz.ProductPropertyMapper;
import com.innovation.ic.cyz.base.mapper.cyz.ProductUniqueMapper;
import com.innovation.ic.cyz.base.model.cyz.Product;
import com.innovation.ic.cyz.base.model.cyz.ProductProperty;
import com.innovation.ic.cyz.base.model.cyz.ProductUnique;
import com.innovation.ic.cyz.base.pojo.enums.RedisKeyPrefixEnum;
import com.innovation.ic.cyz.base.pojo.global.ApiPageResult;
import com.innovation.ic.cyz.base.pojo.global.ServiceResult;
import com.innovation.ic.cyz.base.pojo.variable.cyz.product.ProductQueryRespPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.ps_productunique.PsProdsUniqPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.ps_property.*;
import com.innovation.ic.cyz.base.service.cyz.ProductService;
import com.innovation.ic.cyz.base.vo.pve_standard.ps_productsunique.PsPartNumbersQueryByContextVo;
import com.innovation.ic.cyz.base.vo.pve_standard.ps_productsunique.PsProdsUniqVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author linuo
 * @desc Product表接口实现类
 * @time 2022年10月28日17:31:27
 */
@Service
//@Transactional
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
    @Resource
    private ProductMapper productMapper;

    @Resource
    private ServiceHelper serviceHelper;

    @Resource
    private ProductPropertyMapper productPropertyMapper;

    @Resource
    private BrandMapper brandMapper;

    @Resource
    private ProductUniqueMapper productUniqueMapper;

    /**
     * 清空product表数据
     */
    @Override
    public void truncateProduct() {
        productMapper.truncateProduct();
    }

    /**
     * 批量插入Product表数据
     *
     * @param list 需要插入的数据
     * @return 返回插入结果
     */
    @Override
    public ServiceResult<Boolean> batchInsertProductsList(List<Product> list) throws InterruptedException {
        boolean result = Boolean.FALSE;
        String message = ServiceResult.INSERT_FAIL;

        // 批量保存redis
        //this.batchInsertProductsRedis(list);

        List<Product> insertDataList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            insertDataList.add(list.get(i));
            // insertDataList数据够了10000条进行入库处理
            if (insertDataList.size() == 10000) {
                Integer insertCount = productMapper.insertBatchSomeColumn(insertDataList);
                if (insertCount > 0) {
                    result = Boolean.TRUE;
                    message = ServiceResult.INSERT_SUCCESS;
                    Thread.sleep(200);
                }
                insertDataList = new ArrayList<>();
            } else {
                // 最后一条数据处理完且insertDataList有数据保存到数据库
                if (i == list.size() - 1 && insertDataList.size() > 0) {
                    Integer insertCount = productMapper.insertBatchSomeColumn(insertDataList);
                    if (insertCount > 0) {
                        result = Boolean.TRUE;
                        message = ServiceResult.INSERT_SUCCESS;
                        Thread.sleep(200);
                    }
                    insertDataList = new ArrayList<>();
                }
            }
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setResult(result);
        serviceResult.setSuccess(result);
        serviceResult.setMessage(message);
        return serviceResult;
    }

    /**
     * 型号模糊查询
     *
     * @param psPartNumbersQueryByContextVo 型号模糊查询的vo类
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<List<ProductQueryRespPojo>> queryPartNumbersByContext(PsPartNumbersQueryByContextVo psPartNumbersQueryByContextVo) {
        List<ProductQueryRespPojo> list = productMapper.queryPartNumbersByContext(psPartNumbersQueryByContextVo);

        ServiceResult<List<ProductQueryRespPojo>> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setResult(list);
        return serviceResult;
    }

    @Override
    public Integer total() {
        return this.baseMapper.selectCount(new QueryWrapper<>());
    }

    @Override
    public List<Product> findByPage(int pageNum, int pageSize) {
        int start = pageNum * pageSize;
        int end = start + pageSize;
        if (start > 0) {
            start += 1;
        }
        return this.baseMapper.findByPage(start, end);
    }

    /**
     * 根据分类查询备选属性值
     */
    @Override
    public ServiceResult<PsPropertyResultPojo> getPsProperties(List<String> categoriesList) {
        // 查询属性信息
        List<PsPropertyPojo> psProperties = productPropertyMapper.findProperties(categoriesList);
        if (psProperties != null && !psProperties.isEmpty()) {
            List<String> propertyIds = psProperties.stream().map(t -> t.getPropertyId()).collect(Collectors.toList());
            List<ProductProperty> productPropertyList = productPropertyMapper.findPropertyValuesByPropertyIds(propertyIds);

            psProperties = psProperties.stream().map(item -> {
                List<ProductProperty> thePropertyValues = productPropertyList.stream()
                        .filter(t -> t.getPropertyId().equals(item.getPropertyId()))
                        .collect(Collectors.toList());
                if (thePropertyValues != null && !thePropertyValues.isEmpty()) {
                    List<String> valueText = thePropertyValues.stream().map(t -> t.getText()).collect(Collectors.toList());
                    item.setValueText(valueText);
                }
                return item;
            }).collect(Collectors.toList());
        }

        // 查询品牌信息
        List<PsPropertyBrandPojo> brands = brandMapper.findBrands(categoriesList);

        // 查询封装信息
        List<PsPropertyPackagePojo> packages = productUniqueMapper.findPackages(categoriesList);

        // 查询包装信息
        List<PsPropertyPackingPojo> packings = productUniqueMapper.findPackings(categoriesList);

        PsPropertyResultPojo result = new PsPropertyResultPojo();
        result.setProperties(psProperties);
        result.setBrands(brands);
        result.setPackages(packages);
        result.setPackings(packings);

        ServiceResult<PsPropertyResultPojo> serviceResult = new ServiceResult<>();
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 查询器件选型列表
     *
     * @return
     */
    @Override
    public ServiceResult<ApiPageResult<PsProdsUniqPojo>> getPsProducts(PsProdsUniqVo param) {
        Page<ProductUnique> p = new Page<>(param.getPageIndex(), param.getPageSize());

        IPage<PsProdsUniqPojo> data = productUniqueMapper.getList(p, param);

        List<PsProdsUniqPojo> list = data.getRecords().stream().collect(Collectors.toList());

        ApiPageResult<PsProdsUniqPojo> pageResult = new ApiPageResult<>();
        pageResult.setList(list);
        pageResult.setPageNum(param.getPageIndex());
        pageResult.setPageSize(param.getPageSize());
        pageResult.setTotal(data.getTotal());
        pageResult.setTotalPage(Integer.valueOf(String.valueOf(data.getPages())));
        ServiceResult<ApiPageResult<PsProdsUniqPojo>> serviceResult = new ServiceResult<>();
        serviceResult.setResult(pageResult);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /***
     * 批量保存redis
     * @param list
     */
    private void batchInsertProductsRedis(List<Product> list) {
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_PRODUCT.getCode();
        try {
            List<Product> insertDataList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                insertDataList.add(list.get(i));
                if (i % 10000 == 0 && i != 0) {
                    serviceHelper.getRedisManager().lPushAll(key, insertDataList);
                    this.sleep();
                    insertDataList.clear();
                }
            }
            if (!CollectionUtils.isEmpty(insertDataList)) {
                serviceHelper.getRedisManager().lPushAll(key, insertDataList);
            }
        } catch (Exception e) {
            log.error("定时任务,保存Redis key :  {} 失败 ", key, e);
        }
    }

    /**
     * 线程处理睡眠
     */
    private void sleep() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            log.error("线程睡眠发生异常", e);
        }
    }
}